import { ref, watch, Ref, defineComponent } from 'vue';
import {
  getDataPickerProps,
  getEditorEmits,
  useNamespace,
} from '@ibiz-template/vue3-util';
import { isEmpty } from 'ramda';
import './ibiz-picker.scss';
import { PickerEditorController } from '../picker-editor.controller';

export const IBizPicker = defineComponent({
  name: 'IBizPicker',
  props: getDataPickerProps<PickerEditorController>(),
  emits: getEditorEmits(),
  setup(props, { emit }) {
    const ns = useNamespace('picker');

    const c = props.controller!;

    // 当前值
    const curValue: Ref<Array<string> | string | null> = ref('');

    // 实体数据集
    const items: Ref<IData[]> = ref([]);

    // 是否显示所有数据
    const isShowAll = ref(true);

    // 自动选择Ref
    const pickerAutoCompleteRef = ref();

    watch(
      () => props.value,
      newVal => {
        if (newVal || newVal === null) {
          curValue.value = newVal;
          if (newVal === null) {
            curValue.value = '';
          }
          const value = props.data[c.valueItem];
          const index = items.value.findIndex((item: IData) =>
            Object.is(item[c.keyName], value),
          );
          if (index !== -1) {
            return;
          }
          // items里匹配不到当前值项值时，生成自身的选项
          items.value = [];
          if (!isEmpty(newVal) && !isEmpty(value)) {
            items.value.push({ [c.textName]: newVal, [c.keyName]: value });
          }
        }
      },
      { immediate: true },
    );

    // 处理选中数据后的处理逻辑
    const handleDataSelect = async (data: IData) => {
      // 处理回填数据
      const dataItems = await c.calcFillDataItems(data);
      if (dataItems.length) {
        dataItems.forEach(dataItem => {
          emit('change', dataItem.value, dataItem.id);
        });
      }

      // 处理值项和本身的值
      if (c.valueItem) {
        emit('change', data[c.keyName], c.valueItem);
      }
      emit('change', data[c.textName]);
    };

    // 打开数据选择视图
    const openPickUpView = async (e: MouseEvent) => {
      e.stopPropagation();
      const res = await c.openPickUpView(props.data);
      if (res && res[0]) {
        await handleDataSelect(res[0]);
      }
    };

    // 打开数据链接视图
    const openLinkView = async (e: MouseEvent) => {
      e.stopPropagation();
      const res = await c.openLinkView(props.data);
      if (res && res[0]) {
        await handleDataSelect(res[0]);
      }
    };

    // 往外抛值
    const onACSelect = async (item: IData) => {
      await handleDataSelect(item);
      isShowAll.value = true;
    };

    // 搜索
    const onSearch = async (query: string, cb?: (_items: IData[]) => void) => {
      if (c.model.appDataEntityId) {
        let trimQuery = '';
        if (query !== props.value) {
          trimQuery = query.trim();
        }
        const res = await c.getServiceData(trimQuery, props.data);
        if (res) {
          items.value = res.data as IData[];
          if (cb && cb instanceof Function) {
            cb(items.value);
          }
        }
      }
    };

    // 清除
    const onClear = () => {
      // 清空回填数据
      const dataItems = c.dataItems;
      if (dataItems?.length) {
        dataItems.forEach(dataItem => {
          emit('change', null, dataItem.id);
        });
      }
      if (c.valueItem) {
        emit('change', null, c.valueItem);
      }
      emit('change', null);
    };

    const closeCircle = (c.linkView ? 1 : 0) + (c.pickupView ? 1 : 0);

    // 自动聚焦
    const editorRef = ref();
    if (props.autoFocus) {
      watch(editorRef, newVal => {
        if (newVal) {
          newVal.focus();
        }
      });
    }
    const onFocus = () => {
      emit('focus');
    };
    const onBlur = () => {
      emit('blur');
    };

    return {
      ns,
      c,
      curValue,
      items,
      pickerAutoCompleteRef,
      openPickUpView,
      openLinkView,
      onACSelect,
      onSearch,
      editorRef,
      onClear,
      onFocus,
      onBlur,
      closeCircle,
    };
  },
  render() {
    if (this.readonly) {
      return (
        <div class={(this.ns.b(), this.ns.m('readonly'))}>{this.value}</div>
      );
    }
    return (
      <div class={[this.ns.b(), this.disabled ? this.ns.m('disabled') : '']}>
        {this.c.noAC ? (
          <el-input
            ref='editorRef'
            v-model={this.curValue}
            clearable
            placeholder={this.c.placeHolder}
            onClear={this.onClear}
            disabled={this.disabled}
          >
            {{
              suffix: () => {
                if (this.$slots.append) {
                  return this.$slots.append({});
                }
                if (this.c.noButton) {
                  return;
                }
                return [
                  this.c.model.pickupAppViewId ? (
                    <ion-icon
                      onClick={this.openPickUpView}
                      name='search'
                    ></ion-icon>
                  ) : null,
                  this.c.model.linkAppViewId ? (
                    <ion-icon
                      onClick={this.openLinkView}
                      name='link-arrow'
                    ></ion-icon>
                  ) : null,
                ];
              },
            }}
          </el-input>
        ) : (
          <div
            class={[
              this.ns.e('autocomplete'),
              this.ns.m(this.closeCircle.toString()),
            ]}
          >
            <el-autocomplete
              ref='editorRef'
              v-model={this.curValue}
              value-key={this.c.textName}
              placeholder={this.c.placeHolder}
              clearable
              popper-class={this.ns.e('transfer')}
              fetch-suggestions={this.onSearch}
              onClear={this.onClear}
              onBlur={this.onBlur}
              onFocus={this.onFocus}
              disabled={this.disabled}
            >
              {{
                default: ({ item }: { item: IData }) => {
                  if (this.$slots.append) {
                    return this.$slots.append({});
                  }
                  return (
                    <div
                      class={this.ns.e('transfer-item')}
                      onClick={() => {
                        this.onACSelect(item);
                      }}
                    >
                      {item[this.c.textName]}
                    </div>
                  );
                },
                suffix: () => {
                  if (this.c.noButton) {
                    return;
                  }
                  return [
                    this.c.model.pickupAppViewId ? (
                      <ion-icon
                        onClick={this.openPickUpView}
                        name='search'
                      ></ion-icon>
                    ) : null,
                    this.c.model.linkAppViewId ? (
                      <ion-icon
                        onClick={this.openLinkView}
                        name='link-arrow'
                      ></ion-icon>
                    ) : null,
                  ];
                },
              }}
            </el-autocomplete>
          </div>
        )}
      </div>
    );
  },
});
